//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

namespace Microsoft.Research.ScientificWorkflow.UIDesigner
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Controls;
    using System.Windows.Shapes;
    using System.Windows;
    using System.Windows.Media;

    public class CompositeActivityConnector : Canvas, IUpdatePointPositions
    {
        private Polyline line;
        private ITridentUIElement leftElement;
        private ITridentUIElement rightElement;
        private bool startingElem;

        public CompositeActivityConnector(ITridentUIElement leftElement, ITridentUIElement rightElement)
        {
            this.InitComponents();
            this.leftElement = leftElement;
            this.rightElement = rightElement;
            if (this.rightElement is StartElement)
            {
                this.startingElem = true;
            }
        }

        /// <summary>
        /// Initialize.
        /// </summary>
        private void InitComponents()
        {
            this.line = new Polyline();
            this.line.StrokeThickness = 2;
            this.Children.Add(this.line);
            this.Loaded += new RoutedEventHandler(this.OnLoaded);
        }

        /// <summary>
        /// This is used to update the positions of the connection element
        /// created with respect to the FrameworkElements in teh Activity Elements.
        /// </summary>
        public void UpdatePointPositions()
        {
            Point startPoint;
            Point endPoint;
            int offset = 0;
            FrameworkElement first = null;
            FrameworkElement second = null;

            if (this.startingElem)
            {
                first = this.leftElement.LeftControlFlowConnectionElement;
                second = this.rightElement.LeftControlFlowConnectionElement;
                offset = 7;

                // This will be the start point for the Connectivity Element.
                startPoint = first.TranslatePoint(new Point(first.Width, first.Height / 2.0), this);

                // This will be the End point for the Connectivity Element.
                endPoint = second.TranslatePoint(new Point(0, second.Height / 2.0), this);
            }
            else
            {
                first = this.leftElement.RightControlFlowConnectionElement;
                second = this.rightElement.RightControlFlowConnectionElement;
                offset = -7;

                // This will be the start point for the Connectivity Element.
                startPoint = first.TranslatePoint(new Point(0, first.Height / 2.0), this);

                // This will be the End point for the Connectivity Element.
                endPoint = second.TranslatePoint(new Point(second.Width, second.Height / 2.0), this);
            }

            this.line.Stroke = ((Shape)first).Stroke;

            // Mid Point of the Connectivity Element.
            Point midTopPoint = new Point(startPoint.X + offset, startPoint.Y);
            Point midBotPoint = new Point(startPoint.X + offset, endPoint.Y);

            this.line.Points.Clear();
            this.line.Points.Add(startPoint);
            this.line.Points.Add(midTopPoint);
            this.line.Points.Add(midBotPoint);
            this.line.Points.Add(endPoint);
        }

        /// <summary>
        /// Fired on load of the connector.
        /// </summary>
        /// <param name="sender">
        /// This.
        /// </param>
        /// <param name="e">
        /// RoutedEventArgs
        /// </param>
        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            this.UpdatePointPositions();
        }
    }
}
